home *** CD-ROM | disk | FTP | other *** search
/ Amiga CD32 Gamer 14 / CD32 Gamer - 1995 - Issue 14.iso / fli / flick15.lha / src / c2p_000.s < prev    next >
Text File  |  1994-11-14  |  9KB  |  298 lines

  1. ; Chunky2Planar algorithm, originally by James McCoull
  2. ; Modified by Peter McGavin for variable size and depth
  3. ; and "dirty list" (hope I didn't slow it down too much)
  4. ;
  5. ;     Cpu only solution
  6. ;    Originally optimised for 020+fastram
  7. ;    Tried to optimise for 68000
  8.  
  9. ;void __asm c2p_8 (register __a0 UBYTE *chunky_data,
  10. ;                  register __a1 PLANEPTR raster,
  11. ;                  register __a2 UBYTE *dirty_list,
  12. ;                  register __d1 ULONG plsiz,
  13.  
  14. ; a0 -> width*height chunky pixels in fastmem
  15. ; a1 -> contiguous bitplanes in chipmem
  16. ; a2 -> dirty list (1-byte flag for whether each 32 pixel "unit" needs updating)
  17. ; d1 = width*height/8   (width*height must be a multiple of 32)
  18.  
  19.     ifeq    depth-8
  20.         xdef    _c2p_8_000
  21. _c2p_8_000:
  22.     else
  23.     ifeq    depth-6
  24.         xdef    _c2p_6_000
  25. _c2p_6_000:
  26.     else
  27.     ifeq    depth-4
  28.         xdef    _c2p_4_000
  29. _c2p_4_000:
  30.     else
  31.         fail    "unsupported depth!"
  32.     endc
  33.     endc
  34.     endc
  35.  
  36.  
  37. wordmerge    macro        ;    i1 i2 tmp
  38.                 ;    \1 \2 \3
  39.         move.l    \2,\3    ;  4 \3 = CD
  40.         move.w    \1,\2    ;  4 \2 = CB
  41.         swap    \2    ;  4 \2 = BC
  42.         move.w    \2,\1    ;  4 \1 = AC
  43.         move.w    \3,\2    ;  4 \2 = BD
  44.         endm        ; 20
  45.  
  46.  
  47. merge        macro        ;    io  in out tmp msk sft
  48.                 ;    \1  \2  \3  \4  \5  \6
  49.                 ;    \1 = abqr
  50.                 ;    \2 = ijyz
  51.         move.l    \5,\3    ;  4 \3 = 0x0x
  52.         move.l    \3,\4    ;  4 \4 = 0x0x
  53.         and.l    \1,\3    ;  8 \3 = 0b0r
  54.         and.l    \2,\4    ;  8 \4 = 0j0z
  55.         eor.l    \3,\1    ;  8 \1 = a0q0
  56.         eor.l    \4,\2    ;  8 \2 = i0y0
  57.         lsr.l    #\6,\2    ; 8+2*sft  \2 = 0i0y
  58.     ifeq \6-1
  59.         add.l    \3,\3    ;  8
  60.     else
  61.         lsl.l    #\6,\3    ; 8+2*sft  \3 = b0r0
  62.     endc
  63.         or.l    \2,\1    ;  8 \1 = aiqy
  64.         or.l    \4,\3    ;  8 \3 = bjrz
  65.         endm        ; 72+4*sft
  66.  
  67. merge4        macro        ; io  in out tmp msk
  68.     ifgt depth-4
  69.         merge    \1,\2,\3,\4,\5,4
  70.     else
  71.         move.l    \5,\3    ; this version returns only 1 result
  72.         and.l    \3,\2    ; \2 = 0j0z
  73.         and.l    \1,\3    ; \3 = 0b0r
  74.         lsl.l    #4,\3    ; \3 = b0r0
  75.         or.l    \2,\3    ; \3 = bjrz
  76.     endc
  77.         endm
  78.  
  79.  
  80. ; the real c2p routine starts here
  81.  
  82.         movem.l    d2-d7/a2-a6,-(sp)
  83.  
  84.         sub.w    #24,sp        ; space for temporary variables
  85.  
  86. ; a0 = chunky buffer
  87. ; a1 = output area
  88. ; a2 = dirty list
  89. ; d1 = plsiz
  90.  
  91.         move.l    d1,(4,sp)    ; save plsiz
  92.         lsl.l    #3,d1        ; 8*plsiz
  93.         move.l    a0,(sp)
  94.         add.l    d1,(sp)        ; (sp) -> end of chunky buffer
  95.         sub.l    (4,sp),d1
  96.     ifle depth-6
  97.         sub.l    (4,sp),d1
  98.         sub.l    (4,sp),d1
  99.     endc
  100.     ifle depth-4
  101.         sub.l    (4,sp),d1
  102.         sub.l    (4,sp),d1
  103.     endc
  104.         move.l    d1,(8,sp)    ; save 7*plsiz (or 5*plsiz) (or 3*plsiz)
  105.  
  106.         adda.l    d1,a1        ; a1 -> plane7 (or plane5) (or plane3)
  107.  
  108.         move.l    #$00ff00ff,a3    ; load byte merge mask
  109.         move.l    #$0f0f0f0f,a4    ; load nibble merge mask
  110.  
  111. ; pass 1
  112. initloop:    tst.b    (a2)+        ; does next 32 pixel unit need updating?
  113.         bne.b    c2p        ; branch if yes
  114.  
  115.         adda.w    #32,a0        ; skip 32 pixels on input
  116.         addq.l    #4,a1        ; skip 32 pixels on output
  117.  
  118.         cmpa.l    (sp),a0
  119.         bne.b    initloop
  120.         bra.w    exit        ; exit if no changes
  121.  
  122. ; this becomes the main loop after the first change is found
  123. mainloop:    tst.b    (a2)+        ;  8 does next 32 pixel unit need updating?
  124.         bne.b    c2p        ; 10
  125.  
  126.         adda.w    #32,a0        ; skip 32 pixels on input
  127.         addq.l    #4,a1        ; skip 32 pixels on output
  128.  
  129.         cmpa.l    (sp),a0
  130.         bne.b    mainloop
  131.         bra.w    exit
  132.  
  133. ; convert next 32 pixels and return to mainloop
  134. c2p:        movem.l    (a0)+,d0-d7    ; 76 get 32 pixels in registers
  135.  
  136. ; d0 = a7a6a5a4a3a2a1a0 b7b6b5b4b3b2b1b0 c7c6c5c4c3c2c1c0 d7d6d5d4d3d2d1d0
  137. ; d1 = e7e6e5e4e3e2e1e0 f7f6f5f4f3f2f1f0 g7g6g5g4g3g2g1g0 h7h6h5h4h3h2h1h0
  138. ; d2 = i7i6i5i4i3i2i1i0 j7j6j5j4j3j2j1j0 k7k6k5k4k3k2k1k0 l7l6l5l4l3l2l1l0
  139. ; d3 = m7m6m5m4m3m2m1m0 n7n6n5n4n3n2n1n0 o7o6o5o4o3o2o1o0 p7p6p5p4p3p2p1p0
  140. ; d4 = q7q6q5q4q3q2q1q0 r7r6r5r4r3r2r1r0 s7s6s5s4s3s2s1s0 t7t6t5t4t3t2t1t0
  141. ; d5 = u7u6u5u4u3u2u1u0 v7v6v5v4v3v2v1v0 w7w6w5w4w3w2w1w0 x7x6x5x4x3x2x1x0
  142. ; d6 = y7y6y5y4y3y2y1y0 z7z6z5z4z3z2z1z0 A7A6A5A4A3A2A1A0 B7B6B5B4B3B2B1B0
  143. ; d7 = C7C6C5C4C3C2C1C0 D7D6D5D4D3D2D1D0 E7E6E5E4E3E2E1E0 F7F6F5F4F3F2F1F0
  144.  
  145.         wordmerge d0,d4,a6    ; 20 d0/4 = abqr cdst
  146.         wordmerge d1,d5,a6    ; 20 d1/5 = efuv ghwx
  147.         wordmerge d2,d6,a6    ; 20 d2/6 = ijyz klAB
  148.         wordmerge d3,d7,a6    ; 20 d3/7 = mnCD opEF
  149.  
  150. ; d0 = a7a6a5a4a3a2a1a0 b7b6b5b4b3b2b1b0 q7q6q5q4q3q2q1q0 r7r6r5r4r3r2r1r0
  151. ; d1 = e7e6e5e4e3e2e1e0 f7f6f5f4f3f2f1f0 u7u6u5u4u3u2u1u0 v7v6v5v4v3v2v1v0
  152. ; d2 = i7i6i5i4i3i2i1i0 j7j6j5j4j3j2j1j0 y7y6y5y4y3y2y1y0 z7z6z5z4z3z2z1z0
  153. ; d3 = m7m6m5m4m3m2m1m0 n7n6n5n4n3n2n1n0 C7C6C5C4C3C2C1C0 D7D6D5D4D3D2D1D0
  154. ; d4 = c7c6c5c4c3c2c1c0 d7d6d5d4d3d2d1d0 s7s6s5s4s3s2s1s0 t7t6t5t4t3t2t1t0
  155. ; d5 = g7g6g5g4g3g2g1g0 h7h6h5h4h3h2h1h0 w7w6w5w4w3w2w1w0 x7x6x5x4x3x2x1x0
  156. ; d6 = k7k6k5k4k3k2k1k0 l7l6l5l4l3l2l1l0 A7A6A5A4A3A2A1A0 B7B6B5B4B3B2B1B0
  157. ; d7 = o7o6o5o4o3o2o1o0 p7p6p5p4p3p2p1p0 E7E6E5E4E3E2E1E0 F7F6F5F4F3F2F1F0
  158.  
  159. ; temporarily save off some registers
  160.         movea.l    d6,a6        ;  4
  161.         movea.l    d7,a5        ;  4
  162.  
  163. ; set up pass 2 & 3 masks
  164.         move.l    #$00ff00ff,a3    ;  8
  165.         move.l    #$0f0f0f0f,a4    ;  8
  166.  
  167. ; pass 2
  168.         merge    d0,d2,d6,d7,a3,8 ;104 d0/d6 = aiqy bjrz
  169.         merge    d1,d3,d7,d2,a3,8 ;104 d1/d7 = emuc fnvD
  170.  
  171. ; d0 = a7a6a5a4a3a2a1a0 i7i6i5i4i3i2i1i0 q7q6q5q4q3q2q1q0 y7y6y5y4y3y2y1y0
  172. ; d6 = b7b6b5b4b3b2b1b0 j7j6j5j4j3j2j1j0 r7r6r5r4r3r2r1r0 z7z6z5z4z3z2z1z0
  173. ; d1 = e7e6e5e4e3e2e1e0 m7m6m5m4m3m2m1m0 u7u6u5u4u3u2u1u0 C7C6C5C4C3C2C1C0
  174. ; d7 = f7f6f5f4f3f2f1f0 n7n6n5n4n3n2n1n0 v7v6v5v4v3v2v1v0 D7D6D5D4D3D2D1D0
  175.  
  176. ; pass 3
  177.         merge4    d0,d1,d2,d3,a4,4 ;88 d0/d2  = ae74... ae30...
  178.         merge4    d6,d7,d3,d1,a4,4 ;88 d6/d3  = bf74... bf30...
  179.  
  180. ; d0 = a7a6a5a4e7e6e5e4 i7i6i5i4m7m6m5m4 q7q6q5q4u7u6u5u4 y7y6y5y4C7C6C5C4
  181. ; d2 = a3a2a1a0e3e2e1e0 i3i2i1i0m3m2m1m0 q3q2q1q0u3u2u1u0 y3y2y1y0C3C2C1C0
  182. ; d6 = b7b6b5b4f7f6f5f4 j7j6j5j4n7n6n5n4 r7r6r5r4v7v6v5v4 z7z6z5z4D7D6D5D4
  183. ; d3 = b3b2b1b0f3f2f1f0 j3j2j1j0n3n2n1n0 r3r2r1r0v3v2v1v0 z3z2z1z0D3D2D1D0
  184.  
  185. ; exchange them
  186.         exg    a6,d2        ;  4
  187.         exg    a5,d3        ;  4
  188.  
  189. ; d2 = k7k6k5k4k3k2k1k0 l7l6l5l4l3l2l1l0 A7A6A5A4A3A2A1A0 B7B6B5B4B3B2B1B0
  190. ; d3 = o7o6o5o4o3o2o1o0 p7p6p5p4p3p2p1p0 E7E6E5E4E3E2E1E0 F7F6F5F4F3F2F1F0
  191.  
  192. ; pass 2
  193.         merge    d4,d2,d7,d1,a3,8 ;104 d4/d7 = cksA dltB
  194.         merge    d5,d3,d1,d2,a3,8 ;104 d5/d1 = gowE hpxF
  195.  
  196. ; d4 = c7c6c5c4c3c2c1c0 k7k6k5k4k3k2k1k0 s7s6s5s4s3s2s1s0 A7A6A5A4A3A2A1A0
  197. ; d7 = d7d6d5d4d3d2d1d0 l7l6l5l4l3l2l1l0 t7t6t5t4t3t2t1t0 B7B6B5B4B3B2B1B0
  198. ; d5 = g7g6g5g4g3g2g1g0 o7o6o5o4o3o2o1o0 w7w6w5w4w3w2w1w0 E7E6E5E4E3E2E1E0
  199. ; d1 = h7h6h5h4h3h2h1h0 p7p6p5p4p3p2p1p0 x7x6x5x4x3x2x1x0 F7F6F5F4F3F2F1F0
  200.  
  201. ; pass 3
  202.         merge4    d4,d5,d3,d2,a4,4 ;88 d4/d3 = cg74.. cg30..
  203.         merge4    d7,d1,d5,d2,a4,4 ;88 d7/d5 = dh74.. dh30..
  204.  
  205. ; d4 = c7c6c5c4g7g6g5g4 k7k6k5k4o7o6o5o4 s7s6s5s4w7w6w5w4 A7A6A5A4E7E6E5E4
  206. ; d3 = c3c2c1c0g3g2g1g0 k3k2k1k0o3o2o1o0 s3s2s1s0w3w2w1w0 A3A2A1A0E3E2E1E0
  207. ; d7 = d7d6d5d4h7h6h5h4 l7l6l5l4p7p6p5p4 t7t6t5t4x7x6x5x4 B7B6B5B4F7F6F5F4
  208. ; d5 = d3d2d1d0h3h2h1h0 l3l2l1l0p3p2p1p0 t3t2t1t0x3x2x1x0 B3B2B1B0F3F2F1F0
  209.  
  210. ; set up pass 4 & 5 masks
  211.         move.l    #$33333333,a3    ;  8
  212.         move.l    #$55555555,a4    ;  8
  213.  
  214.     ifgt depth-4
  215. ; pass 4
  216.         merge    d0,d4,d1,d2,a3,2 ;80 d0/d1 = aceg76.. aceg54..
  217.         merge    d6,d7,d4,d2,a3,2 ;80 d6/d4 = bdhf76.. bdhf54..
  218.  
  219. ; d0 = a7a6c7c6e7e6g7g6 i7i6k7k6m7m6o7o6 q7q6s7s6u7u6w7w6 y7y6A7A6C7C6E7E6
  220. ; d1 = a5a4c5c4g5g4e5e4 i5i4k5k4m5m4o5o4 q5q4s5s4u5u4w5w4 y5y4A5A4C5C4E5E4
  221. ; d6 = b7b6d7d6f7f6h7h6 j7j6l7l6n7n6p7p6 r7r6t7t6v7v6x7x6 z7z6B7B6D7D6F7F6
  222. ; d4 = b5b4d5d4h5h4f5f4 j5j4l5l4n5n4p5p4 r5r4t5t4v5v4x5x4 z5z4B5B4D5D4F5F4
  223.  
  224. ; pass 5
  225.     ifgt depth-6
  226.         merge    d0,d6,d7,d2,a4,1 ;74 d0/d7 = abcd7... abcd6...
  227.     endc
  228.         merge    d1,d4,d6,d2,a4,1 ;74 d1/d6 = abcd5... abcd4...
  229.  
  230. ; d0 = a7b7c7d7e7f7g7h7 i7j7k7l7m7n7o7p7 q7r7s7t7u7v7w7x7 y7z7A7B7C7D7E7F7
  231. ; d7 = a6b6c6d6e6f6g6h6 i6j6k6l6m6n6o6p6 q6r6s6t6u6v6w6x6 y6z6A6B6C6D6E6F6
  232. ; d1 = a5b5c5d5g5h5e5f5 i5j5k5l5m5n5o5p5 q5r5s5t5u5v5w5x5 y5z5A5B5C5D5E5F5
  233. ; d6 = a4b4c4d4g4h4e4f4 i4j4k4l4m4n4o4p4 q4r4s4t4u4v4w4x4 y4z4A4B4C4D4E4F4
  234.  
  235.     endc
  236.  
  237.         move.l    (4,sp),d2    ; 12 d2 = plsiz
  238.  
  239.     ifgt depth-4
  240.     ifgt depth-6
  241.         move.l    d0,(a1)        ;  8 plane7
  242.         suba.l    d2,a1        ;  8 -plsiz
  243.         move.l    d7,(a1)        ;  8 plane6
  244.         suba.l    d2,a1        ;  8 -plsiz
  245.     endc
  246.         move.l    d1,(a1)        ;  8 plane5
  247.         suba.l    d2,a1        ;  8 -plsiz
  248.         move.l    d6,(a1)        ;  8 plane4
  249.         suba.l    d2,a1        ;  8 -plsiz
  250.     endc
  251.  
  252. ; restore them
  253.         move.l    a6,d1        ;  4
  254.         move.l    a5,d7        ;  4
  255.  
  256. ; d1 = a3a2a1a0e3e2e1e0 i3i2i1i0m3m2m1m0 q3q2q1q0u3u2u1u0 y3y2y1y0C3C2C1C0
  257. ; d7 = b3b2b1b0f3f2f1f0 j3j2j1j0n3n2n1n0 r3r2r1r0v3v2v1v0 z3z2z1z0D3D2D1D0
  258. ; d3 = c3c2c1c0g3g2g1g0 k3k2k1k0o3o2o1o0 s3s2s1s0w3w2w1w0 A3A2A1A0E3E2E1E0
  259. ; d5 = d3d2d1d0h3h2h1h0 l3l2l1l0p3p2p1p0 t3t2t1t0x3x2x1x0 B3B2B1B0F3F2F1F0
  260.  
  261. ; pass 4
  262.         merge    d1,d3,d6,d0,a3,2 ;80 d1/d6 = aceg32.. aceg10..
  263.         merge    d7,d5,d0,d3,a3,2 ;80 d7/d0 = bdhf32.. bdhf10..
  264.  
  265. ; d1 = a3a2c3c2e3e2g3g2 i3i2k3k2m3m2o3o2 q3q2s3s2u3u2w3w2 y3y2A3A2C3C2E3E2
  266. ; d6 = a1a0c1c0g1g0e1e0 i1i0k1k0m1m0o1o0 q1q0s1s0u1u0w1w0 y1y0A1A0C1C0E1E0
  267. ; d7 = b3b2d3d2f3f2h3h2 j3j2l3l2n3n2p3p2 r3r2t3t2v3v2x3x2 z3z2B3B2D3D2F3F2
  268. ; d0 = b1b0d1d0h1h0f1f0 j1j0l1l0n1n0p1p0 r1r0t1t0v1v0x1x0 z1z0B1B0D1D0F1F0
  269.  
  270. ; pass 5
  271.         merge    d1,d7,d5,d3,a4,1 ;74 d1/d5 = abcd3... abcd2...
  272.         merge    d6,d0,d7,d3,a4,1 ;74 d6/d7 = abcd1... abcd0...
  273.  
  274. ; d1 = a3b3c3d3e3f3g3h3 i3j3k3l3m3n3o3p3 q3r3s3t3u3v3w3x3 y3z3A3B3C3D3E3F3
  275. ; d5 = a2b2c2d2e2f2g2h2 i2j2k2l2m2n2o2p2 q2r2s2t2u2v2w2x2 y2z2A2B2C2D2E2F2
  276. ; d6 = a1b1c1d1g1h1e1f1 i1j1k1l1m1n1o1p1 q1r1s1t1u1v1w1x1 y1z1A1B1C1D1E1F1
  277. ; d7 = a0b0c0d0g0h0e0f0 i0j0k0l0m0n0o0p0 q0r0s0t0u0v0w0x0 y0z0A0B0C0D0E0F0
  278.  
  279.         move.l    d1,(a1)        ;  8 plane3
  280.         suba.l    d2,a1        ;  8 -plsiz
  281.         move.l    d5,(a1)        ;  8 plane2
  282.         suba.l    d2,a1        ;  8 -plsiz
  283.         move.l    d6,(a1)        ;  8 plane1
  284.         suba.l    d2,a1        ;  8 -plsiz
  285.         move.l    d7,(a1)+    ;  8 plane 0
  286.         adda.l    (8,sp),a1    ; 18 +7*plsiz (or 5*plsiz) (or 3*plsiz)
  287.  
  288.         cmp.l    (sp),a0        ; 14
  289.         bne.w    mainloop    ; 10 end of main loop
  290.  
  291.                     ;1788 cycles = 55.9 cycles/pixel
  292. exit:
  293.         add.w    #24,sp
  294.         movem.l    (sp)+,d2-d7/a2-a6
  295.         rts
  296. end:
  297.         end
  298.